import MaterialLoader from "../MaterialLoader";

const { ccclass, menu, executeInEditMode, requireComponent, property } = cc._decorator;

@ccclass
@menu('自定义组件/点击高亮组件')
export default class ClickLightShader extends cc.Component {


    @property({
        displayName: "亮度",
        tooltip: "0-1,0不亮,1全白",
    })
    /**阈值 */
    threshold: number = 0.3;

    // @property({
    //     displayName: "材质(可选)",
    //     type: cc.Material,
    // })
    material: cc.Material = null;

    _btn: cc.Button = null;

    /**节点下的所有精灵 数组 */
    _sp_list: cc.Sprite[] = [];
    _url: null;
    _isTouchCancel = null;
    onLoad() {
        this._btn = this.node.getComponent(cc.Button);
        this._loadMaterial();

    }

    start() {
        this._getSprite(this.node);
    }

    //获取节点下的所有精灵
    _getSprite(node) {
        let sp = node.getComponent(cc.Sprite);
        if (sp) {
            this._sp_list.push(sp);
        }
        let len = node.children.length;
        for (let i = 0; i < len; i++) {
            let item = node.children[i];
            if (item) {
                this._getSprite(item);
            }
        }
    }
    _loadMaterial() {
        //无数据时
        if (!this.material)
            MaterialLoader.loadRes("ClickLightShader", (res) => {
                if (this.node && this.node.isValid) {

                    this.material = res;
                    this.node.on(cc.Node.EventType.TOUCH_START, this.on_touchStart.bind(this), this)
                    this.node.on(cc.Node.EventType.TOUCH_END, this.on_touchEnd.bind(this), this)
                    this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.on_touchCancel.bind(this), this)
                    this.node.on(cc.Node.EventType.TOUCH_MOVE, this.on_touchMove.bind(this), this)
                }
            })
    }
    onEnable() {
        //存在点击材质和精灵时才启用
        if (this.material && this._sp_list.length) {
            this.node.on(cc.Node.EventType.TOUCH_START, this.on_touchStart.bind(this), this)
            this.node.on(cc.Node.EventType.TOUCH_END, this.on_touchEnd.bind(this), this)
            this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.on_touchCancel.bind(this), this)
            this.node.on(cc.Node.EventType.TOUCH_MOVE, this.on_touchMove.bind(this), this)
        }
    }
    onDisable() {
        if (this.material && this._sp_list.length) {
            this.node.off(cc.Node.EventType.TOUCH_START, this.on_touchStart.bind(this))
            this.node.off(cc.Node.EventType.TOUCH_END, this.on_touchEnd.bind(this))
            this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.on_touchCancel.bind(this))
            this.node.off(cc.Node.EventType.TOUCH_MOVE, this.on_touchMove.bind(this))
        }
    }

    _checkButtonEnable() {
        if (this._btn) {
            return this._btn.interactable ? true : false;
        }
        return true;
    }
    on_touchStart(event) {
        // console.warn("按下")
        this._isTouchCancel = false;
        if (!this._checkButtonEnable()) return;
        this.setMaterialAndProperty(this._sp_list, "alpha", this.threshold, 0, this.material);
    }
    on_touchCancel(event) {
        // console.warn("取消")
        this._isTouchCancel = true;
        if (!this._checkButtonEnable()) return;
        this.setMaterialAndProperty(this._sp_list, "alpha", 0, 0, this.material);

    }
    on_touchEnd(event) {
        // console.warn("抬起")
        if (!this._checkButtonEnable()) return;
        this.setMaterialAndProperty(this._sp_list, "alpha", 0, 0, this.material);

    }
    on_touchMove(event: cc.Touch) {
        // console.warn("移动")
        if (!this._checkButtonEnable()) return;

        //已经触发取消, 那么不再接受移动消息
        if (this._isTouchCancel) {
            return;
        }

        let location = this.node.convertToNodeSpaceAR(event.getLocation())
        if (!cc.rect(-this.node.width / 2, -this.node.height / 2, this.node.width, this.node.height).contains(location)) {
            this.setMaterialAndProperty(this._sp_list, "alpha", 0, 0);
        } else {
            this.setMaterialAndProperty(this._sp_list, "alpha", this.threshold, 0, this.material);
        }
    }


    /**
     * 
     * 对精灵数组设置材质,并且传入值
     * 
     * @param sp_list 精灵数组
     * @param key 传入值键
     * @param value 传入值值
     * @param index 材质序号
     * @param material 材质(可选),不存在时不设置
     */
    setMaterialAndProperty(sp_list: cc.Sprite[], key: string, value: any, index: number = 0, material?: cc.Material) {
        let len = sp_list.length;
        for (let i = 0; i < len; i++) {
            let item = sp_list[i];
            if (item) {
                //下一帧运行,错开按钮的重置shader方法

                this.scheduleOnce(() => {
                    if (material) {
                        item.setMaterial(index, material);
                    }

                    let materialIns = item.getMaterial(index);
                    if (materialIns.effect._properties[key]) {
                        materialIns.setProperty(key, value);
                    }
                })


            }
        }
    }


}